import { Cell, Node } from '@antv/x6';
import { ConditionTypeEnum, NodeTypeEnum } from '../constant';

/**
 * EL表达式的模型表示：数据结构本质上是一个树形结构。
 * 例如一个串行编排(THEN)：
 * (1) EL表达式形式：THEN(a, b, c, d)
 * (2) JSON表示形式：
 * {
    type: ConditionTypeEnum.THEN,
    children: [
      { type: NodeTypeEnum.COMMON, id: 'a' },
      { type: NodeTypeEnum.COMMON, id: 'b' },
      { type: NodeTypeEnum.COMMON, id: 'c' },
      { type: NodeTypeEnum.COMMON, id: 'd' },
    ],
  }
 */
export default class ELNode {
  constructor() {
    // 节点类型：可以是编排类型，也可以是组件类型
    this.type = null;
    // 当前节点的子节点：编排类型有子节点，组件类型没有子节点
    this.children = [];
    // 当前节点的父节点
    this.parent = null;
    // 判断类节点类型：主要用于SWITCH/IF/FOR/WHILE等编排类型
    this.condition = null;
    // 组件节点的id
    this.id = null;
    // 编排节点的属性：可以设置id/tag等等
    this.properties = {};
    // 当前节点的X6 Cell内容
    this.cells = [];
    // 当前节点的X6 Node内容
    this.nodes = [];
    // 代理节点
    this.proxy = null;
    // 当前操作符节点的开始节点
    this.startNode = null;
    // 当前操作符节点的结束节点
    this.endNode = null;
    // 是否折叠
    this.collapsed = false;
  }

  /**
   * 在后面添加子节点
   * @param newNode 子节点
   * @param index 指定位置：可以是索引，也可以是兄弟节点
   */
  appendChild(newNode, index) {
    newNode.parent = this;
    if (this.children) {
      // 尝试在父节点中添加新节点
      if (typeof index === 'number') {
        // 1. 如果有索引
        this.children.splice(index, 0, newNode);
        return true;
      }
      if (index) {
        // 2. 如果有目标节点
        const _index = this.children.indexOf(index);
        if (_index !== -1) {
          this.children.splice(_index + 1, 0, newNode);
          return true;
        }
        if (this.condition === index) {
          // 3. 如果是在condition之后追加
          return this.appendChild(newNode, 0);
        }
      }
      // 4. 否则直接插入
      this.children.push(newNode);
      return true;
    }
    return false;
  }

  /**
   * 在前面添加子节点
   * @param newNode 子节点
   * @param index 指定位置：可以是索引，也可以是兄弟节点
   */
  prependChild(newNode, index) {
    newNode.parent = this;
    if (this.children) {
      if (typeof index === 'number') {
        this.children.splice(index, 0, newNode);
        return true;
      }
      if (index) {
        const _index = this.children.indexOf(index);
        if (_index !== -1) {
          this.children.splice(_index, 0, newNode);
          return true;
        }
        if (this.condition === index) {
          return this.prependChild(newNode, 0);
        }
      }
      this.children.unshift(newNode);
      return true;
    }
    return false;
  }

  /**
   * 移除子节点
   * @param child 子节点
   */
  removeChild(child) {
    if (this.children) {
      const index = this.children.indexOf(child);
      if (index !== -1) {
        this.children.splice(index, 1);
        child.parent = null;
        return true;
      }
    }
    return false;
  }

  /**
   * 在当前节点前面插入新节点
   * @param newNode 新节点
   */
  prepend(newNode) {
    if (this.parent) {
      const index = this.parent.children.indexOf(this);
      return this.parent.prependChild(newNode, index);
    }
    return false;
  }

  /**
   * 在当前节点后面插入新节点
   * @param newNode 新节点
   */
  append(newNode) {
    if (this.parent) {
      const index = this.parent.children.indexOf(this);
      return this.parent.appendChild(newNode, index + 1);
    }
    return false;
  }

  /**
   * 移除当前节点
   */
  remove() {
    if (this.parent) {
      return this.parent.removeChild(this);
    }
    return false;
  }

  /**
   * 替换当前节点
   * @param newNode 新节点
   */
  replace(newNode) {
    if (this.parent) {
      const index = this.parent.children.indexOf(this);
      if (index !== -1) {
        this.parent.children[index] = newNode;
        newNode.parent = this.parent;
        this.parent = null;
        return true;
      }
    }
    return false;
  }

  /**
   * 替换子节点
   * @param oldNode 旧节点
   * @param newNode 新节点
   */
  replaceChild(oldNode, newNode) {
    if (this.children) {
      const index = this.children.indexOf(oldNode);
      if (index !== -1) {
        this.children[index] = newNode;
        newNode.parent = this;
        oldNode.parent = null;
        return true;
      }
    }
    return false;
  }

  /**
   * 转换为X6 Cell数组
   */
  toCells(options = {}) {
    return [];
  }

  /**
   * 获取选中的节点
   */
  selectNodes() {
    return this.nodes.filter(node => node.isSelected());
  }

  /**
   * 获取所有节点
   */
  getNodes() {
    const nodes = [...this.nodes];
    if (this.children) {
      this.children.forEach(child => {
        nodes.push(...child.getNodes());
      });
    }
    return nodes;
  }

  /**
   * 获取所有Cell
   */
  getCells() {
    const cells = [...this.cells];
    if (this.children) {
      this.children.forEach(child => {
        cells.push(...child.getCells());
      });
    }
    return cells;
  }

  /**
   * 重置Cell
   */
  resetCells(cells = [], nodes = []) {
    this.cells = cells;
    this.nodes = nodes;
  }

  /**
   * 获取开始节点
   */
  getStartNode() {
    return this.startNode;
  }

  /**
   * 获取结束节点
   */
  getEndNode() {
    return this.endNode;
  }

  /**
   * 添加节点
   */
  addNode(node) {
    this.nodes.push(node);
    return node;
  }

  /**
   * 获取属性
   */
  getProperties() {
    return this.properties || {};
  }

  /**
   * 设置属性
   */
  setProperties(properties) {
    this.properties = { ...this.properties, ...properties };
  }

  /**
   * 属性转换为EL表达式
   */
  propertiesToEL() {
    const properties = this.getProperties();
    if (properties.id) {
      return `.id("${properties.id}")`;
    }
    return '';
  }

  /**
   * 转换为EL表达式
   */
  toEL(prefix = '') {
    return '';
  }

  /**
   * 转换为JSON
   */
  toJSON() {
    const json = {
      type: this.type,
      collapsed: this.collapsed
    };

    if (this.id) {
      json.id = this.id;
    }

    if (this.properties && Object.keys(this.properties).length > 0) {
      json.properties = this.properties;
    }

    if (this.children && this.children.length > 0) {
      json.children = this.children.map(child => child.toJSON());
    }

    if (this.condition) {
      json.condition = this.condition.toJSON();
    }

    return json;
  }

  /**
   * 判断是否为指定节点的父节点
   */
  isParentOf(model) {
    if (!model || !this.children) {
      return false;
    }

    for (const child of this.children) {
      if (child === model || child.isParentOf(model)) {
        return true;
      }
    }

    return false;
  }

  /**
   * 判断是否折叠
   */
  isCollapsed() {
    return this.collapsed;
  }

  /**
   * 切换折叠状态
   */
  toggleCollapse(collapsed) {
    this.collapsed = collapsed !== undefined ? collapsed : !this.collapsed;
  }
}

/**
 * 属性接口
 */
export class Properties {
  constructor() {
    this.id = null;
    this.tag = null;
  }
}

/**
 * 节点数据接口
 */
export class NodeData {
  constructor() {
    this.model = null;
    this.toolbar = {
      prepend: false,
      append: false,
      delete: false,
      replace: false,
      collapse: false
    };
  }
}

/**
 * 属性转字符串
 */
function propertyToString(propertyValue) {
  if (typeof propertyValue === 'string') {
    return `"${propertyValue}"`;
  }
  return String(propertyValue);
} 